package mate.dart.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.Random;
import java.util.Vector;

import javax.swing.Box;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import mate.dart.AbstractGame;
import mate.dart.ThrowEvent;
import mate.dart.utils.Utils;

public class GameKillerScoreBoard extends AbstractGame {

	private static final long serialVersionUID = 3926113017222630148L;
	final String name = "Killer";
	
	private static int currentNumber;	
	static Vector<Integer> amountOfHited = new Vector<Integer>();

	private int numberOfPlayers = 2;	
	int currentPlayer = 0;
	int throwsNumber = 0;
	PlayerCounter[] players = new PlayerCounter[numberOfPlayers];
	
	int round = 1;	
	JTextField textRound = new JTextField("1");	
	JLabel leftDarts = new JLabel("Left datrs : 3");

	public GameKillerScoreBoard() {
		currentNumber = nextNumber();
		
		initComponents();				
	}

	private void initComponents() {		
		setLayout(new BorderLayout());
		
		players = new PlayerCounter[numberOfPlayers];
		for(int i=0; i< numberOfPlayers; i++) {
			players[i] = new PlayerCounter();
		}

		Box vBox = Box.createVerticalBox();
		vBox.add(Box.createVerticalStrut(20));
		JLabel label = new JLabel("You are playing the Killer");
		label.setFont(Utils.getSmallFont());
		vBox.add(label);
		vBox.add(Box.createVerticalStrut(20));

		label = new JLabel("Round: ");
		label.setFont(Utils.getSmallFont());

		textRound.setMaximumSize(new Dimension(30, 30));
		textRound.setFont(Utils.getSmallFont());
		textRound.setHorizontalAlignment(JTextField.RIGHT);
		label.setLabelFor(textRound);
		Box box = Box.createHorizontalBox();
		box.add(label);
		box.add(textRound);		
		vBox.add(box);
		
		box = Box.createHorizontalBox();
		for (int i = 0; i < numberOfPlayers; i++) {
			box.add(players[i]);
		}
		vBox.add(box);
		vBox.add(Box.createVerticalStrut(120));
		leftDarts.setFont(Utils.getSmallFont());
		vBox.add(leftDarts);
		add(vBox);		
		colorCounters();
	}

	private boolean isAllClosed() {
		for (PlayerCounter p : players){
			if (p.getCount() != 3 ) return false;
		}
		return true;		
	}
	@Override
	public void clear() {
		throwsNumber = 0;
		currentPlayer = 0;
		round = 0;
		amountOfHited.clear();
		currentNumber = nextNumber();
		incRound();
		for (PlayerCounter p : players) {
			p.clear();
		}
		leftDarts.setText("Left Darts: 3");
		colorCounters();
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public void setPlayers(int players) {
		removeAll();
		numberOfPlayers = players;
		initComponents();
	}

	public void newThrowEvent(ThrowEvent event) {
		throwsNumber++;		
		leftDarts.setText("Left darts :" + (3 - throwsNumber));

		PlayerCounter player = players[currentPlayer];
		int num = event.getNum();
		int count = event.getCount();
		int pCount = player.getCount();
		int toAdd = 3 - pCount;
		
		if (num == currentNumber) {
			if (toAdd > count) {
				player.addCount(count);
			} else {
				player.addCount(toAdd);
				if (isAllClosed() ) {					
					currentNumber = nextNumber();
					if (currentNumber != 0) {						
						for(PlayerCounter p : players) {
							p.nextNumber(currentNumber);
						}
					}
				} else {
					for (PlayerCounter p : players)
						if (p != player && p.getCount() != 3) {
							p.addPoints((count - toAdd)*currentNumber);
						}
				}
			}
		} else {
			player.addPoints(num * count);
		}		
		if (throwsNumber == 3) {
			if (currentPlayer == numberOfPlayers - 1) incRound();
			changePlayer();
		}

	}
	
	private void incRound() {
		round = Integer.parseInt(textRound.getText());
		round++;
		textRound.setText(round + "");
	}
	
	private void changePlayer() {
		currentPlayer = (currentPlayer + 1 ) % numberOfPlayers;
		throwsNumber = 0;
		leftDarts.setText("Left Darts: 3");
		colorCounters();
	}
	
	private void colorCounters() {
		for (PlayerCounter p : players) {
			p.lightLabels(players[currentPlayer] == p);
		}
	}
	
	private int nextNumber() {
		if (amountOfHited.size() < 7) {
			int i;
			while (amountOfHited.contains(i = randomNumber()));
			amountOfHited.add(i);
			return i;
		}
		return 0;
	}

	//returns a pseudorandom int value between 1 to 20 plus 25
	private int randomNumber() {
		Random rand = new Random();
		int i = rand.nextInt(21);
		if (i == 0)	i = 25;
		return i;
	}

	

	private static class PlayerCounter extends JPanel {

		private static final long serialVersionUID = 1L;

		JTextField pointsField = new JTextField("0");

		JTextField playerName = new JTextField("name");

		JTextField[] labels = new JTextField[7]; 

		public PlayerCounter() {
			initComponents();
			setPreferredSize(new Dimension(200, 300));
		}

		private void initComponents() {
			setLayout(new GridLayout(9, 1));

			playerName.setFont(Utils.getSmallFont());
			add(playerName);

			pointsField.setFont(Utils.getNormalFont());
			add(pointsField);

			for (int i = 0; i < 7; i++) {
				if (i == 0) {
					labels[i] = new JTextField(String.valueOf(numberToString(currentNumber)));
					labels[i].setBackground(getBackground());
					labels[i].setBorder(BorderFactory.createEmptyBorder());
					labels[i].setOpaque(true);
					labels[i].setFont(Utils.getNormalFont());
					add(labels[i]);
				} else {
					JTextField l = new JTextField("");
					l.setFont(Utils.getNormalFont());
					labels[i] = l;
					l.setOpaque(true);
					l.setBorder(BorderFactory.createEmptyBorder());
					l.setBackground(getBackground());
					add(l);
				}
			}
		}
		
		private void nextNumber(int number) {
			labels[amountOfHited.size() - 1].setText(numberToString(number));
		}
		
		private String numberToString(int number) {
			int i = number;
			StringBuilder s = new StringBuilder();
			s.append(i);
			if (i - 10 < 0) {
				s.append(" ");
			}
			return s.toString();
		}

		public void lightLabels(boolean light) {
			for (JTextField l : labels) {
				if (light) {
					l.setBackground(Color.green);
				} else {
					l.setBackground(getBackground());
				}
			}
		}
		
		public int getCount() {
			int i = labels[amountOfHited.size() - 1].getText().lastIndexOf("x");
			if (i == -1) {
				return 0;
			} else {
				return i -1;
			}	
			           
		}
		
		public void addCount(int count) {
			StringBuilder s = new StringBuilder();
			for (int i = 0; i < count; i++) {
				s.append("x");
			}

			int index = amountOfHited.size() - 1;
			labels[index].setText(labels[index].getText() + s.toString());
		}
		
		public void addPoints(int points) {
			pointsField
					.setText((Integer.parseInt(pointsField.getText()) + points)
							+ "");
		}

		public void clear() {
			pointsField.setText("0");
			for (int i = 0; i < 7; i++) {
				if (i == 0) {
					labels[i].setText(String.valueOf(numberToString(currentNumber)));
				} else {
					labels[i].setText("");
				}
			}
			lightLabels(false);
		}

	}

}
